package cn.js.sip.rat.task.service.impl;

import cn.js.sip.rat.system.dto.AjaxResult;
import cn.js.sip.rat.system.page.TableDataInfo;
import cn.js.sip.rat.system.service.impl.BaseServiceImpl;
import cn.js.sip.rat.task.entity.JobInfoEntity;
import cn.js.sip.rat.task.mapper.TaskMapper;
import cn.js.sip.rat.task.quartz.QuartzJobExecution;
import cn.js.sip.rat.task.service.TaskService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.quartz.*;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;

/**
 * @ClassName: cn.js.sip.rat.task.service.impl
 * @Description: TODO
 * @author: xuxiaoli
 * @Date: 2020-01-13   20:36
 */
@Service("taskService")
public class TaskServiceImpl extends BaseServiceImpl<JobInfoEntity> implements TaskService {
    @Resource
    private SchedulerFactoryBean schedulerFactoryBean;
    @Resource
    private TaskMapper taskMapper;

    @Override
    public void update(JobInfoEntity entity) {
        entity.setLastModifyInfo();
        QueryWrapper wrapper=new QueryWrapper();
        JobInfoEntity jobInfoEntity=new JobInfoEntity();
        jobInfoEntity.setId(entity.getId());
        wrapper.setEntity(jobInfoEntity);
        taskMapper.update(entity,wrapper);
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        this.createJob(scheduler, entity);
    }

    @Override
    public void save(JobInfoEntity entity) {
        entity.setCreateInfo();
        taskMapper.insert(entity);
    }

    @Override
    public JobInfoEntity findById(String id) {
        return taskMapper.selectById(id);
    }

    @PostConstruct
    public void init() {
        List<JobInfoEntity> jobList = taskMapper.selectList(null);
        for (JobInfoEntity job : jobList) {
            this.createJob(schedulerFactoryBean.getScheduler(), job);
        }
    }

    @Override
    public void run(JobInfoEntity jobInfoEntity) {
        try {
            JobInfoEntity entity = taskMapper.selectById(jobInfoEntity.getId());
            createJob(schedulerFactoryBean.getScheduler(), entity);
            schedulerFactoryBean.getScheduler().triggerJob(JobKey.jobKey(entity.getJobName(), entity.getJobGroup()));
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    @Override
    public TableDataInfo query(JobInfoEntity job) {
        Page page = new Page(1, 10);
        Page selectPage = taskMapper.selectPage(page, null);
        return super.getDataTable(selectPage);
    }

    @Override
    public boolean checkCronExpressionIsValid(String cronExpression) {
        return CronExpression.isValidExpression(cronExpression);
    }

    @Override
    public AjaxResult deleteByIds(List<String> ids) {
        ids.forEach(id -> {
            JobInfoEntity jobInfoEntity = taskMapper.selectById(id);
            try {
                schedulerFactoryBean.getScheduler().deleteJob(JobKey.jobKey(jobInfoEntity.getJobName(), jobInfoEntity.getJobGroup()));
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
        });
        taskMapper.deleteBatchIds(ids);
        return AjaxResult.success();

    }

    @Override
    public void changeStatus(JobInfoEntity newJob) {
        try {
            if (newJob.getStatus().equals(0)) {
                schedulerFactoryBean.getScheduler().resumeJob(JobKey.jobKey(newJob.getJobName(), newJob.getJobGroup()));
            } else {
                schedulerFactoryBean.getScheduler().pauseJob(JobKey.jobKey(newJob.getJobName(), newJob.getJobGroup()));
            }
            QueryWrapper wrapper=new QueryWrapper();
            JobInfoEntity jobInfoEntity = new JobInfoEntity();
            jobInfoEntity.setId(newJob.getId());
            wrapper.setEntity(jobInfoEntity);
            taskMapper.update(newJob,wrapper);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }

    }

    private void createJob(Scheduler scheduler, JobInfoEntity entity){
        // 构建job信息
        String jobId = entity.getId();
        JobInfoEntity jobInfoEntity = taskMapper.selectById(jobId);
        String jobName = jobInfoEntity.getJobName();
        String jobGroup = jobInfoEntity.getJobGroup();
        JobDetail jobDetail = JobBuilder.newJob(QuartzJobExecution.class).withIdentity(JobKey.jobKey(jobName, jobGroup)).build();
        // 表达式调度构建器
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(jobInfoEntity.getCronExpression());
        // 按新的cronExpression表达式构建一个新的trigger
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(TriggerKey.triggerKey(jobName,jobGroup))
                .withSchedule(cronScheduleBuilder).build();
        // 放入参数，运行时的方法可以获取
        jobDetail.getJobDataMap().put("entity", jobInfoEntity);
        // 判断是否存在

        try {
            if (scheduler.checkExists(JobKey.jobKey(jobName, jobGroup))) {
                // 防止创建时存在数据问题 先移除，然后在执行创建操作
                scheduler.deleteJob(JobKey.jobKey(jobName, jobGroup));
            }
            scheduler.scheduleJob(jobDetail, trigger);

            if (jobInfoEntity.getStatus().equals(1)) {
                scheduler.pauseJob(JobKey.jobKey(jobName, jobGroup));
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

}
